/**
 * 链接跳转指令
 * 为页面中的外部链接添加跳转提示框
 */

import Vue from 'vue';

let linkJumpPrompt = null;

// 获取链接跳转提示框实例
function getLinkJumpPrompt() {
  if (!linkJumpPrompt) {
    // 尝试从Vue原型上获取
    if (Vue.prototype.$linkJumpPrompt) {
      linkJumpPrompt = Vue.prototype.$linkJumpPrompt;
      return linkJumpPrompt;
    }
    
    // 如果原型上没有，创建一个新实例
    const LinkJumpPromptConstructor = Vue.extend({
      template: '<mj-link-jump-prompt ref="promptRef"></mj-link-jump-prompt>'
    });
    
    const instance = new LinkJumpPromptConstructor();
    const vm = instance.$mount();
    document.body.appendChild(vm.$el);
    linkJumpPrompt = vm.$refs.promptRef;
    
    // 设置到Vue原型上供全局使用
    Vue.prototype.$linkJumpPrompt = linkJumpPrompt;
  }
  
  return linkJumpPrompt;
}

// 缓存已处理过的链接，避免重复处理
const processedLinks = new WeakMap();

// 可信任的域名列表(示例)，这些域名不会显示跳转提示
const trustedDomains = [
//   'kingcola-icg.cn',
//   'github.com',
//   'kingcola-icg.github.io'
];

// 检查链接是否为外部链接
function isExternalLink(url) {
  if (!url) return false;
  
  // 排除javascript:void(0)和javascript:类型的链接
  if (url.startsWith('javascript:')) {
    return false;
  }
  
  // 如果是邮件链接或电话链接，不视为外部链接
  if (url.startsWith('mailto:') || url.startsWith('tel:')) {
    return false;
  }
  
  // 如果是完整的URL（包含协议）
  if (/^https?:\/\//i.test(url)) {
    try {
      const urlObj = new URL(url);
      const currentHost = window.location.hostname;
      
      // 检查是否是可信任域名
      if (isTrustedDomain(urlObj.hostname)) {
        return false;
      }
      
      // 如果域名不同，则为外部链接
      return urlObj.hostname !== currentHost;
    } catch (e) {
      console.error('解析URL时出错:', e);
      return false;
    }
  }
  
  // 如果以//开头（协议相对URL）
  if (url.startsWith('//')) {
    return true;
  }
  
  // 如果以/开头，则为站内链接
  if (url.startsWith('/')) {
    return false;
  }
  
  // 如果以#开头，则为页内锚点
  if (url.startsWith('#')) {
    return false;
  }
  
  // 其他情况，默认为外部链接
  return true;
}

// 检查是否是可信任域名
function isTrustedDomain(hostname) {
  return trustedDomains.some(domain => {
    // 检查完全匹配或子域名匹配
    return hostname === domain || hostname.endsWith('.' + domain);
  });
}

// 设置链接的图标和样式
function decorateExternalLink(link) {
  // 添加外部链接样式类
  link.classList.add('external-link');
  
  // 如果链接中没有图标，添加一个图标
  const hasIcon = Array.from(link.children).some(child => 
    child.tagName === 'I' || child.tagName === 'SVG' || child.classList.contains('icon')
  );
  
  if (!hasIcon && !link.querySelector('.external-icon')) {
    const icon = document.createElement('span');
    icon.className = 'external-icon';
    icon.setAttribute('aria-hidden', 'true');
    link.appendChild(icon);
  }
  
  // 添加安全提示
  link.setAttribute('rel', 'noopener noreferrer nofollow');
  link.removeAttribute('target'); // 移除可能存在的target属性
}

/**
 * 处理链接元素，添加点击事件
 */
function processLinkElement(link) {
  // 如果已经处理过这个链接，跳过
  if (processedLinks.has(link)) {
    return;
  }
  
  // 获取链接地址
  const href = link.getAttribute('href');
  
  // 如果不是链接或没有href属性，跳过
  if (!href) return;
  
  // 如果是外部链接，则处理
  if (isExternalLink(href)) {
    // 装饰链接元素
    decorateExternalLink(link);
    
    // 阻止原始点击事件的执行
    link.addEventListener('click', function(e) {
      e.preventDefault();
      e.stopPropagation();
      
      // 获取提示框实例
      const prompt = getLinkJumpPrompt();
      if (prompt) {
        // 设置URL并显示提示框
        prompt.show(href);
      } else {
        console.error('链接跳转提示框不可用');
        // 如果提示框不可用，直接在新窗口打开
        window.open(href, '_blank', 'noopener,noreferrer');
      }
    }, true);
    
    // 标记为已处理
    processedLinks.set(link, true);
  }
}

/**
 * 处理容器内的所有链接
 */
function processAllLinks(container, options = {}) {
  // 默认选择器和排除项
  const selector = options.selector || 'a';
  const exclude = options.exclude || [];
  
  // 找到所有符合条件的链接
  const links = container.querySelectorAll(selector);
  
  links.forEach(link => {
    // 检查是否在排除列表中
    const isExcluded = exclude.some(excl => {
      if (typeof excl === 'string') {
        return link.matches(excl);
      }
      return false;
    });
    
    if (!isExcluded) {
      processLinkElement(link);
    }
  });
}

// 使用MutationObserver监听DOM变化，处理动态加载的链接
function setupLinkObserver(options = {}) {
  const exclude = options.exclude || [];
  
  // 创建观察者实例
  const observer = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
      // 处理新添加的节点
      if (mutation.type === 'childList') {
        mutation.addedNodes.forEach(node => {
          // 如果是元素节点
          if (node.nodeType === 1) {
            // 如果是链接元素本身
            if (node.tagName === 'A') {
              const isExcluded = exclude.some(excl => node.matches(excl));
              if (!isExcluded) {
                processLinkElement(node);
              }
            }
            
            // 如果是容器元素，处理其中的所有链接
            const links = node.querySelectorAll('a');
            links.forEach(link => {
              const isExcluded = exclude.some(excl => link.matches(excl));
              if (!isExcluded) {
                processLinkElement(link);
              }
            });
          }
        });
      }
      
      // 处理属性变化，如果href属性发生变化
      if (mutation.type === 'attributes' && mutation.attributeName === 'href') {
        const link = mutation.target;
        if (link.tagName === 'A') {
          const isExcluded = exclude.some(excl => link.matches(excl));
          if (!isExcluded) {
            // 清除之前的处理状态
            processedLinks.delete(link);
            processLinkElement(link);
          }
        }
      }
    });
  });
  
  // 配置观察选项
  const config = {
    childList: true,
    subtree: true,
    attributes: true,
    attributeFilter: ['href']
  };
  
  // 开始观察文档
  observer.observe(document.body, config);
  
  return observer;
}

// 链接跳转指令定义
export const linkJump = {
  // 绑定时
  bind(el, binding) {
    // 仅处理a标签
    if (el.tagName.toLowerCase() !== 'a') return;
    
    // 处理链接元素
    processLinkElement(el);
  },
  
  // 更新时
  update(el, binding) {
    // 仅处理a标签
    if (el.tagName.toLowerCase() !== 'a') return;
    
    // 处理链接元素
    processLinkElement(el);
  }
};

// 自动处理指令
export const autoLinkJump = {
  // 绑定时
  bind(el, binding) {
    // 首次绑定时处理
    processAllLinks(el, binding.value);
  },
  
  // 插入到DOM时
  inserted(el, binding) {
    // 确保DOM插入后再次处理
    setTimeout(() => {
      processAllLinks(el, binding.value);
    }, 0);
  },
  
  // 组件更新时
  update(el, binding) {
    // 组件更新时延迟处理
    setTimeout(() => {
      processAllLinks(el, binding.value);
    }, 0);
  },
  
  // 更新完成后
  componentUpdated(el, binding) {
    // 组件更新完成后再次处理
    setTimeout(() => {
      processAllLinks(el, binding.value);
    }, 100);
  }
};

// 手动处理页面上的所有外部链接
export function processPageLinks(options = {}) {
  processAllLinks(document, options);
}

// 单例观察者实例
let linkObserver = null;

// 开始观察DOM变化
export function startLinkObserver(options = {}) {
  if (!linkObserver) {
    linkObserver = setupLinkObserver(options);
  }
  return linkObserver;
}

// 停止观察
export function stopLinkObserver() {
  if (linkObserver) {
    linkObserver.disconnect();
    linkObserver = null;
  }
}

export default {
  install(Vue) {
    Vue.directive('link-jump', linkJump);
    Vue.directive('auto-link-jump', autoLinkJump);
    
    // 添加全局方法
    Vue.prototype.$processPageLinks = processPageLinks;
    Vue.prototype.$startLinkObserver = startLinkObserver;
    Vue.prototype.$stopLinkObserver = stopLinkObserver;
  }
};